package cn.edu.lingnan.utils;

import cn.edu.lingnan.controllerV1.ChatDto;
import cn.edu.lingnan.mapper.QuestionStoreMapper;
import cn.edu.lingnan.service.QuestionsService;
import cn.edu.lingnan.user.dtos.Result;
import cn.edu.lingnan.user.pojos.AIQuestion;
import cn.edu.lingnan.user.pojos.QuestionStore;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ai.openai.OpenAiChatModel;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class AiJudgementUtils {
    @Autowired
    private AIChatUtils aiChatUtils;


    @Autowired
    private QuestionsService questionsService;

    @Autowired
    private QuestionStoreMapper questionStoreMapper;



    private final static String PRE_MESSAGE = "帮我评分，我会给出题目，作答者的答案和标准答案给你，还有题目的分值，请你帮我评分。注意：\n"
            + "1. 严格按照评分标准，不能轻易给分\n"
            + "2. 评分结果需要同时包含得分和扣分理由\n"
            + "3. 直接返回JSON格式结果，不要包含其他说明\n\n"
            + "题目信息：\n";

    private final static String JSON_FORMAT = "\n请严格使用以下JSON格式返回结果（不要包含markdown语法）：\n"
            + "{\n"
            + "  \"score\": 得分,\n"
            + "  \"feedback\": \"扣分理由\"\n"
            + "}";

    @Autowired
    private OpenAiChatModel chatModel;

    /**
     * 执行AI评分
     *
     * @param question       题目
     * @param userAnswer    用户答案
     * @param correctAnswer 标准答案
     * @param questionScore 题目分值
     * @return 包含评分结果和反馈的JSON对象
     */
    public JSONObject judgement(String question, String userAnswer, String correctAnswer, int questionScore) {
        String promptText = buildPrompt(question, userAnswer, correctAnswer, questionScore);
        String response = processChat(promptText);
        return parseResponse(response);
    }

    /**
     * 构建评分提示语
     */
    private String buildPrompt(String question, String userAnswer, String correctAnswer, int questionScore) {
        return PRE_MESSAGE
                + "题目：" + question + "\n"
                + "用户答案：" + userAnswer + "\n"
                + "标准答案：" + correctAnswer + "\n"
                + "题目分值：" + questionScore + "分\n"
                + JSON_FORMAT;
    }

    /**
     * 处理聊天请求（同步方式）
     */
    private String processChat(String promptText) {
        final StringBuilder fullResponse = new StringBuilder();
        final CountDownLatch latch = new CountDownLatch(1);

        Prompt prompt = new Prompt(new UserMessage(promptText));

        chatModel.stream(prompt).subscribe(
                response -> fullResponse.append(response.getResult().getOutput().getContent()),
                error -> {
                    System.err.println("处理异常，已接收内容：" + fullResponse);
                    latch.countDown();
                },
                () -> latch.countDown()
        );

        try {
            latch.await(30, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("请求处理超时", e);
        }

        return fullResponse.toString();
    }

    /**
     * 解析API响应
     */
    private JSONObject parseResponse(String response) {
        try {
            return JSONObject.parseObject(response);
        } catch (Exception e) {
            throw new RuntimeException("解析AI响应失败，响应内容：" + response, e);
        }
    }

      /*
    向AI发送信息，返回一个AIQuestion的JSON字符串
     */
    public Result createAIQuestion(ChatDto chatDto) {
        // 参数校验
        if (chatDto==null || StrUtil.isBlank(chatDto.getPrompt())) {
            return Result.error("问题内容不能为空");
        }

        String prompt = createPrompt(chatDto);
        log.info("prompt:{}", prompt);
//        String questionJSON = aiChatUtils.processChat(prompt);
        String questionJSON= null;
        try {
            questionJSON = OpenAIChatStreaming.chatStream(prompt);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("原始响应:{}", questionJSON);

        // 空响应处理
        if (StrUtil.isBlank(questionJSON)) {
            log.error("AI返回空内容 | question: {}", chatDto);
            return Result.error("AI响应异常");
        }
            // 清理Markdown代码块标记
            String cleanJson = questionJSON
                    .replaceAll("```json", "")  // 移除头部标记
                    .replaceAll("```", "")      // 移除尾部标记
                    .trim();
            // 解析为Java对象
            AIQuestion aiQuestion = JSONUtil.toBean(cleanJson, AIQuestion.class);
            return questionsService.insertQuestionByAI(aiQuestion);
    }


    private String createPrompt(ChatDto chatDto) {
        String basePrompt = """
    {
        "instruction": "请严格按以下规则解析题目:",
        "rules": [
            "questionVo 是页面显示的原始字符串",
            "questionName 必须生成题目的完整原文内容，不是用户提问的内容",
            "题目难度: 1-简单 2-中等 3-困难",
            "题目类型: 1-单选题，2-多选题，3-判断题，4-填空题，5-简答题",
            "简答题/判断题: questionOption 留空，correctAnswer 必须包含完整解答过程",
            "多选题答案格式: ["A","B"]",
            "判断题答案格式: true或者false，有且只有这两个单词，没有额外解释之类的",
            "填空题答案格式: 正确答案1|正确答案2",
            "storeName 必须解析且不能为空"
            "options结构要求: [{\\"optionKey\\":\\"A\\",\\"optionValue\\":\\"内容\\"},...]"
        ],
        "example": {
            "questionVo": "求函数 f(x) = x^3 - 3x^2 + 2x 的极值点。请分步解答。",
            "storeName": "高等数学题库",
            "questionType": 5,
            "questionName": "求函数 f(x) = x^3 - 3x^2 + 2x 的极值点", 
            "correctAnswer": "解题过程：求导：f'(x) = 3x² - 6x + 2， 令导数为零：3x² - 6x + 2 = 0， 解得 x = (6 ± √12)/6 = 1 ± (√3)/3， 验证二阶导数得两个极值点",
            "questionLevel": 2,
            "questionScore": 10,
            "options": [
                {"optionKey": "A", "optionValue": "F=ma"},
                {"optionKey": "B", "optionValue": "E=mc²"},
                {"optionKey": "C", "optionValue": "F=μN"},
                {"optionKey": "D", "optionValue": "P=IV"}
            ]  //这里是选择题的响应示例，判断题，填空题和简答题这里为空
        },
        "responseFormat": {
            "requiredFields": [
                "questionVo", 
                "questionName",
                "storeName",
                "questionType",
                "correctAnswer",
                "questionLevel",
                "questionScore",
                "options"
            ],
            "notes": [
                "直接返回标准JSON，不要代码块标记",
                "数学符号保留Unicode编码",
                "optionKey使用大写字母"
            ]
        }
    }
    """;
        //查询题库名
        QuestionStore store = questionStoreMapper.getStoreById(chatDto.getStoreId());
        String questionType= switch (chatDto.getQuestionType()) {
            case 1 -> "单选题";
            case 2 -> "多选题";
            case 3 -> "判断题";
            case 4 -> "填空题";
            case 5 -> "简答题";
            default -> "未知";
        };

        return basePrompt + "\n待解析用户提问: 请帮我为" +store.getStoreName()+"生成一道关于"+chatDto.getPrompt()+"的"+questionType;
    }
}